/**
 * Project oo_thread
 */


#include "TaskQueue.h"
#include <iostream>

using std::endl;
using std::cout;
/**
 * TaskQueue implementation
 */


/**
 * @param size
 */
TaskQueue::TaskQueue(size_t size)
:_queSize(size)
,_mutex()
,_notEmpty(_mutex)
,_notFull(_mutex)
,_flag(false)
{


}
//实现full
bool TaskQueue::full()
{
    return _que.size() == _queSize;
}

//实现empty
bool TaskQueue::empty()
{
    return _que.size() == 0;
}
/**
 * @return int
 */
Task * TaskQueue::pop() {
    //加锁
    MutexLockGuard autolock(_mutex);
    //先判断队列是否是空的
    //空的则等待
    while(empty() && !_flag)
    {
        //防止虚假唤醒
        _notEmpty.wait();
    
    }
    if(!_flag)
    {
        //非空则将首元素弹出
        Task *task= _que.front();
        _que.pop();
        //通知等待的生产者线程
        _notFull.notify();
        return task;
    }
    else
    {
        return nullptr;
    }
}

/**
 * @param int
 * @return void
 */
void TaskQueue::push(Task *task) {
    MutexLockGuard autolock(_mutex);
    //现判断是否满
    //满的话则等待
    while(full())
    {
        _notFull.wait();
    }
    //不满则push
    _que.push(task);
    //通知等待的线程
    _notEmpty.notify();
}

void TaskQueue::wakeup()
{
    _notEmpty.notifyAll();
    _flag = true;
}
